<?php
abstract class Model_Factory {
    /**
     * @var Model_Factory
     */
    private static $_instance;
    
    /**
     * Return a concrete implementation for Model_AuthService interface
     * used to perform users management
     * 
     * @return Model_UserService
     */
    public abstract function getUserService();
    
    /**
     * Return a concrete implementation for Model_UserService interface
     * used to perform users authentication
     * 
     * @return Model_AuthService
     */
    public abstract function getAuthService();
    
    /**
     * Return a concrete implementation for Model_FeedService interface
     * used to perform tasks on Feeds
     *  
     * @return Model_FeedService
     */
    public abstract function getFeedService();
    
    /**
     * Return a concrete implementation for Model_CategoryService interface
     * used to perform tasks on Categories
     *  
     * @return Model_CategoryService
     */
    public abstract function getCategoryService();
    
    /**
     * Return a concrete implementation for Model_BoxService interface
     * used to perform tasks on Boxes
     *  
     * @return Model_BoxService
     */
    public abstract function getBoxService();
    
    /**
     * Return a concrete implementation for Model_NewsService interface
     * used to perform tasks on News
     *  
     * @return Model_NewsService
     */
    public abstract function getNewsService();
    
    /**
     * Protected contructor
     * Prevent direct instantiation of this class for singleton pattern
     */
    protected function __construct() {
    }
    
    /**
     * Retunr a concrete implementation for Model_Factory interface
     * 
     * @return Model_Factory
     */
    public static function getInstance() {
        if (self::$_instance == null) {
            throw new Exception('You have to instantiate the factory before using it');
        }
        return self::$_instance;
    }
    
    /**
     * Set the concrete instance to be used
     * 
     * @param Model_Factory $factory
     * @return void
     */
    public static function setInstance(Model_Factory $factory) {
        if (self::$_instance != null) {
            throw new Exception('You have to instantiate the factory only once');
        }
        self::$_instance = $factory;
        
    }
}